﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
{
  public class PreserveReferencesHandlingObject
  {
    #region Types
    public class Directory
    {
      public string Name { get; set; }
      public Directory Parent { get; set; }
      public IList<File> Files { get; set; }
    }

    public class File
    {
      public string Name { get; set; }
      public Directory Parent { get; set; } 
    }
    #endregion

    public void Example()
    {
      #region Usage
      Directory root = new Directory { Name = "Root" };
      Directory documents = new Directory { Name = "My Documents", Parent = root };

      File file = new File { Name = "ImportantLegalDocument.docx", Parent = documents };

      documents.Files = new List<File> { file };

      try
      {
        JsonConvert.SerializeObject(documents, Formatting.Indented);
      }
      catch (JsonSerializationException)
      {
        // Self referencing loop detected for property 'Parent' with type
        // 'Newtonsoft.Json.Tests.Documentation.Examples.ReferenceLoopHandlingObject+Directory'. Path 'Files[0]'.
      }

      string preserveReferenacesAll = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings
        {
          PreserveReferencesHandling = PreserveReferencesHandling.All
        });

      Console.WriteLine(preserveReferenacesAll);
      // {
      //   "$id": "1",
      //   "Name": "My Documents",
      //   "Parent": {
      //     "$id": "2",
      //     "Name": "Root",
      //     "Parent": null,
      //     "Files": null
      //   },
      //   "Files": {
      //     "$id": "3",
      //     "$values": [
      //       {
      //         "$id": "4",
      //         "Name": "ImportantLegalDocument.docx",
      //         "Parent": {
      //           "$ref": "1"
      //         }
      //       }
      //     ]
      //   }
      // }

      string preserveReferenacesObjects = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings
      {
        PreserveReferencesHandling = PreserveReferencesHandling.Objects
      });

      Console.WriteLine(preserveReferenacesObjects);
      // {
      //   "$id": "1",
      //   "Name": "My Documents",
      //   "Parent": {
      //     "$id": "2",
      //     "Name": "Root",
      //     "Parent": null,
      //     "Files": null
      //   },
      //   "Files": [
      //     {
      //       "$id": "3",
      //       "Name": "ImportantLegalDocument.docx",
      //       "Parent": {
      //         "$ref": "1"
      //       }
      //     }
      //   ]
      // }
      #endregion
    }
  }
}